﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.Web.UI.WebControls;
using Logic.BusinessLogic;
using SocialConfig;

public partial class Controls_Posting_PostStatus : System.Web.UI.UserControl
{
    public enum PostState
    {
        SingleAccount,
        MultipleAccounts,
        MultipleMaterAccount
    }

    public bool IsPostALink
    {
        get
        {
            Regex regx = new Regex(@"^(((?<Protocol>\w+):\/\/)|(www\.))(?<Domain>[\w@][\w.:@]+)\/?[\w\.?=%&=\-@/$,]*$", RegexOptions.IgnoreCase);
            MatchCollection mactches = regx.Matches(tbText.Text);
            return mactches.Count > 0;
        }
    }

    public PostState State { get; set; }

    public BO.Account SingleAccount { get; set; }

    public List<BO.Account> OptionalAccounts { get; set; }

    public List<BO.MasterAccount> OptionalMasterAccounts { get; set; }

    public BO.User User { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        InitValidation();
        if (!IsPostBack)
            LoadData();
    }

    private void InitValidation()
    {
        vText.GroupName("post").Required("*");
    }

    private void LoadData()
    {
        cblAccounts.Visible = !(State == PostState.SingleAccount);

        switch (State)
        {
            case PostState.SingleAccount:
                snSelector.SetAvailability(SingleAccount.GetAvailableNetworks());
                break;
            case PostState.MultipleAccounts: DisplayOptionalAccounts(); break;
            case PostState.MultipleMaterAccount: DisplayOptionalMasterAccounts();
                break;
            default:
                break;
        }
    }

    private void DisplayOptionalMasterAccounts()
    {
        var accounts = OrderMasterAccountsByName(OptionalMasterAccounts);
        cblAccounts.DataSource = accounts;
        cblAccounts.DataBind();
    }

    private void DisplayOptionalAccounts()
    {
        var accounts = OrderAccountsByName(OptionalAccounts);
        cblAccounts.DataSource = accounts;
        cblAccounts.DataBind();
    }

    protected void lbtnPost_Click(object sender, EventArgs e)
    {
        if (!Page.IsValid)
            return;

        var sn = snSelector.GetSelector();

        switch (State)
        {
            case PostState.SingleAccount: lblMsg.Text = PostToSingleAccount(sn);
                break;
            case PostState.MultipleAccounts: lblMsg.Text = PostToMultipleAccounts(sn);
                break;
            case PostState.MultipleMaterAccount: lblMsg.Text = PostToMasterAccounts(sn);
                break;
            default:
                break;
        }
    }

    private string PostToMasterAccounts(Logic.BusinessLogic.SocialNetworks.SnSelector sn)
    {
        IEnumerable<int> selected = GetSelectedIDs();

        var accounts = OptionalMasterAccounts.Where(m => selected.Contains(m.ID));
        //Configs configs = GetMasterAccountConfigs(sn, accounts);
        var result = Posting.POstToMasterAccounts(User.ID, accounts, tbText.Text, sn, IsPostALink);

        return "Your post will be published to all accounts associated with the master accounts you selected";
    }

    private Configs GetMasterAccountConfigs(Logic.BusinessLogic.SocialNetworks.SnSelector sn, IEnumerable<BO.MasterAccount> accounts)
    {
        Configs c = new Configs();
        foreach (var account in accounts)
        {
            if (sn.IsFacebook)
                c.fbGraphConfig.Add(new SocialNetworks.Config.FbGraphConfig());//FIXME: need to implement with the right constructor
            if (sn.IsTwitter)
                c.twitterConfig.Add(new SocialNetworks.Config.TwitterConfig());//FIXME: need to implement with the right constructor
            //if (sn.IsWordPress)
            //    c.wordPressConfig.Add(new SocialNetworks.Config.WordPressConfig());
            if (sn.IsYoutube)
                c.youTubeConfig.Add(new SocialNetworks.Config.YouTubeConfig());//FIXME: need to implement with the right constructor
        }

        return c;
    }

    private Configs GetAccountConfigs(Logic.BusinessLogic.SocialNetworks.SnSelector sn, IEnumerable<BO.Account> accounts)
    {
        Configs c = new Configs();
        foreach (var account in accounts)
        {
            if (sn.IsFacebook)
                c.fbGraphConfig.Add(new SocialNetworks.Config.FbGraphConfig());//FIXME: need to implement with the right constructor
            if (sn.IsTwitter)
                c.twitterConfig.Add(new SocialNetworks.Config.TwitterConfig());//FIXME: need to implement with the right constructor
            //if (sn.IsWordPress)
            //    c.wordPressConfig.Add(new SocialNetworks.Config.WordPressConfig());
            if (sn.IsYoutube)
                c.youTubeConfig.Add(new SocialNetworks.Config.YouTubeConfig());//FIXME: need to implement with the right constructor
        }

        return c;
    }

    private IEnumerable<int> GetSelectedIDs()
    {
        IEnumerable<int> selected = cblAccounts.Items.Cast<ListItem>()
                                    .Where(i => i.Selected)
                                    .Select(i => int.Parse(i.Value));
        return selected;
    }

    private string PostToMultipleAccounts(Logic.BusinessLogic.SocialNetworks.SnSelector sn)
    {
        var selected = GetSelectedIDs();

        //var accounts = OptionalAccounts.Where(a => selected.Contains(a.ID));

        var accountIds = OptionalAccounts.Where(a => selected.Contains(a.ID)).Select(a => a.ID);

        //Configs configs = GetAccountConfigs(sn, accounts);

        var result = Posting.PostToAccounts(User.ID, accountIds, tbText.Text, sn, IsPostALink);

        return "Your post will be published to all the accounts you selected";
    }

    private string PostToSingleAccount(Logic.BusinessLogic.SocialNetworks.SnSelector sn)
    {
        PostingResult result;
        if (!IsPostALink)
            result = Posting.PostStatusLine(User.ID, SingleAccount.ID, tbText.Text, sn);
        else result = Posting.PostLink(User.ID, SingleAccount.ID, tbText.Text, sn);

        string report = string.Format("your post <br /> was {0}published on facebook <br /> was {1}published on twitter",
            result.PublishedNetworks.IsFacebook ? "" : "not ",
            result.PublishedNetworks.IsTwitter ? "" : "not ");
        return report;
    }

    private IOrderedEnumerable<BO.MasterAccount> OrderMasterAccountsByName(List<BO.MasterAccount> masterAccountsList, bool Descending = false)
    {
        switch (Descending)
        {
            case true:
                return OptionalMasterAccounts.OrderByDescending(d => d.Name);
            case false:
                return OptionalMasterAccounts.OrderBy(d => d.Name);
            default:
                break;
        }
        return masterAccountsList as IOrderedEnumerable<BO.MasterAccount>;
    }

    private IOrderedEnumerable<BO.Account> OrderAccountsByName(List<BO.Account> accountsList, bool Descending = false)
    {
        switch (Descending)
        {
            case true:
                return OptionalAccounts.OrderByDescending(d => d.Name);
            case false:
                return OptionalAccounts.OrderBy(d => d.Name);
            default:
                break;
        }
        return accountsList as IOrderedEnumerable<BO.Account>;
    }
}